package com.hiof.connection.observers;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Message;
import at.abraxas.amarino.Amarino;
import at.abraxas.amarino.AmarinoIntent;
import com.hiof.Configuration;
import com.hiof.connection.ConnectionManager;
import com.hiof.connection.DataReceiveHandler;
import com.hiof.utility.Utility;

import java.util.ArrayList;

/**
 * Created by IntelliJ IDEA.
 * User: manish
 * Date: 4/9/12
 * Time: 9:27 PM
 * To change this template use File | Settings | File Templates.
 */
public class BluetoothConnectionManager implements Runnable, ConnectionManager {
    boolean connected = false;
    private static final String TAG = "Bluetooth connection";
    ArrayList<ConnectionObserver> observers;
    private static BluetoothConnectionManager instance;
    private static final String BLUETOOTH_DEVICE_MAC_ADDRESS = "00:06:66:08:5F:AE";
    DataReceiveHandler dataReceiveHandler;

    public static BluetoothConnectionManager getInstance() {
        if (null == instance) {
            instance = new BluetoothConnectionManager();
        }
        return instance;
    }

    private BluetoothConnectionManager() {
        observers = new ArrayList<ConnectionObserver>();
        dataReceiveHandler = new DataReceiveHandler();
        Configuration.getInstance().getCurrentContext().registerReceiver(bluetoothReceiver, new IntentFilter(AmarinoIntent.ACTION_RECEIVED));
    }

    public void destroy() {
        this.close();
        if (observers != null) {
            observers.clear();
            observers = null;
        }
        if (dataReceiveHandler != null) {
            dataReceiveHandler = null;
        }
        if (instance != null) {
            instance = null;
        }
    }

    private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                String data = null;
                // the device address from which the data was sent, we don't need it here but to demonstrate how you retrieve it
                final String address = intent.getStringExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS);
                Utility.debug(this.getClass().toString(), "bluetooth address:" + address);

                // the type of data which is added to the intent
                final int dataType = intent.getIntExtra(AmarinoIntent.EXTRA_DATA_TYPE, -1);

                // we only expect String data though, but it is better to check if really string was sent
                // later Amarino will support differnt data types, so far data comes always as string and
                // you have to parse the data to the type you have sent from Arduino, like it is shown below
                if (dataType == AmarinoIntent.STRING_EXTRA) {
                    data = intent.getStringExtra(AmarinoIntent.EXTRA_DATA);
                    Utility.debug(this.getClass().toString(), "Bluetooth connection: " + data);
                    if (data != null) {

                        // since we know that our string value is an int number we can parse it to an integer
                        if ("N".equals(data)) {
                            Message m = new Message();
                            Bundle b = new Bundle();
                            b.putString("message", "next");
                            m.setData(b);
                            dataReceiveHandler.sendMessage(m);
                        } else if ("P".equals(data)) {
                            Message m = new Message();
                            Bundle b = new Bundle();
                            b.putString("message", "previous");
                            m.setData(b);
                            dataReceiveHandler.sendMessage(m);
                        } else if ("C".equals(data)) {
                            Message m = new Message();
                            Bundle b = new Bundle();
                            b.putString("message", "cancel");
                            m.setData(b);
                            dataReceiveHandler.sendMessage(m);
                        } else if ("S".equals(data)) {
                            Message m = new Message();
                            Bundle b = new Bundle();
                            b.putString("message", "select");
                            m.setData(b);
                            dataReceiveHandler.sendMessage(m);
                        }
                    }
                } else {
                    Utility.debug(this.getClass().toString(), "Bluetooth connection: no data");
                }
            } catch (Exception e) {
                Utility.error(this.getClass().toString(), "Bluetooth exception: " + e.getMessage());
            }
        }
    };

    @Override
    public void open() {
        if (!connected)
            Amarino.connect(Configuration.getInstance().getCurrentContext(), BLUETOOTH_DEVICE_MAC_ADDRESS);
        connected = true;
    }

    @Override
    public void close() {
        if (connected) {
            Amarino.disconnect(Configuration.getInstance().getCurrentContext(), BLUETOOTH_DEVICE_MAC_ADDRESS);
            Configuration.getInstance().getCurrentContext().unregisterReceiver(bluetoothReceiver);
            bluetoothReceiver = null;
        }
        connected = false;
    }

    @Override
    public void restart() {
    }

    @Override
    public void registerObserver(ConnectionObserver observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(ConnectionObserver observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {

    }

    @Override
    public void run() {

    }
    public boolean isConnected(){
        return connected;
    }
}
